问题描述(难度困难)
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
You may assume nums1 and nums2 cannot be both empty.
Example 1:
1 | nums1 = [1, 3] |
Example 2:
1 | nums1 = [1, 2] |
方法一:归并排序思想
归并排序在merge之后会将各个有序的子数组合并为一个数组,这里采用归并排序sort的思想,时间和空间复杂度为O(m+n)。用两个index去遍历,每次将最小的整合到一个新的list中,直到整个都遍历完成,需要注意当一个列表遍历完成之后的极端情况。整合的流程如下:
方法一代码
1 | public double findMedianSortedArrays(int[] nums1, int[] nums2) { |
方法二:固定和双指针遍历
方法一中我们其实是把问题转换为了归并排序归并问题,但是实际上并不需要扫描全部的记录,并且也不需要存储整合之后排序的所有的结果,时间复杂度为O(min(m,n)/2,leetcode上大部分说是O(log(min(m,n))),可能理解还不够到位,先记录下吧,空间复杂度为1。这里介绍另一种方式:
大概的思路就是两个数组都维持一个索引位置,两个索引位置需要满足index_first+index_second=(length1+length2-1)/2-1,只有当first_left小于second_right并且second_left小于first_right的时候表示找到了中位数的位置,不然改变其中一个的位置。感觉这个公式还是蛮难理解的,可以理解为在两个数组之间画一条分割线,分割在中间就需要满足index=(length-1)/2。
这里还需要注意一种情况就是当index_first==-1和index_second==-1时first_left和second_left用Integer.MIN_VALUE代替,index_first == length1-1和index_second=length2-1时first_right和second_right用Integer.MAX_VALUE代替。
方法二代码
1 | //1.记录当前划分位置的前后节点 |
总结
两种方式感觉还是第一种理解和书写上更加简单明了,第二种方式在理解和书写上相对困难,而且实际表现出的性能优化也没有特别夸张,可能在非常大的数据量上会表现更加好。